package com.voole.service.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ResourceServlet;

import com.sun.tracing.dtrace.Attributes;
import com.voole.dao.SysActionDao;
import com.voole.dao.SysAuthorityDao;
import com.voole.dao.SysCatalogDao;
import com.voole.dao.SysResourceDao;
import com.voole.dao.SysRoleActionDao;
import com.voole.entity.SysAction;
import com.voole.entity.SysAuthority;
import com.voole.entity.SysCatalog;
import com.voole.entity.SysResource;
import com.voole.entity.SysRoleAction;
import com.voole.entity.SysUser;
import com.voole.service.IMenuService;
import com.voole.service.ISysActionService;
import com.voole.service.ISysAuthorityService;
import com.voole.service.ISysCatalogService;
import com.voole.service.ISysResourceService;
import com.voole.service.ISysUserService;

@Service
@Transactional(propagation = Propagation.REQUIRED)
public class MenuServiceImpl implements IMenuService {

	@Autowired
	private SysAuthorityDao sysAuthorityDao;
	@Autowired
	private ISysAuthorityService sysAuthorityService;
	@Autowired
	private SysCatalogDao sysCatalogDao;
	@Autowired
	private ISysCatalogService sysCatalogService;
	@Autowired
	private SysResourceDao sysResourceDao;
	@Autowired
	private ISysResourceService sysResourceService;
	@Autowired
	private SysActionDao sysActionDao;
	@Autowired
	private ISysActionService sysActionService;
	@Autowired
	private SysRoleActionDao sysRoleActionDao;
	
	/**
	 * 获取目录菜单结构（顶侧，左侧主，左侧次）
	 */
	public List<SysAuthority> getMenuList() throws Exception {
		List<SysAuthority> authorityList = sysAuthorityService.getList();
		for(SysAuthority authority : authorityList){
			List<SysCatalog> catalogList = sysCatalogService.getListByAuthorityId(authority.getId());
			for(SysCatalog catalog: catalogList){
				List<SysResource> resourceList = sysResourceService.getListByCatalogId(catalog.getId());
				catalog.setResourceList(resourceList);
			}
			authority.setCatalogList(catalogList);
		}
		return authorityList;
	}

	/**
	 * 删除目录菜单
	 * @param menuLv 目录等级
	 * @param menuId 目录id
	 */
	public Map<String, Object> delMenu(String menuLv, String menuId) throws Exception{
		Map<String, Object> result = new HashMap<String, Object>();
		
		//删除方向：4级 -> 1级, 不然会找不到而无法删除
		if(StringUtils.isEmpty(menuLv) || StringUtils.isEmpty(menuId)){
			result.put("msg", "操作失败, 菜单等级 或 菜单ID 获取失败");
			return result;
		}
		
		else if("1".equals(menuLv)){
			sysActionDao.delListByAuthorityId(Integer.parseInt(menuId));
			sysResourceDao.delListByAuthorityId(Integer.parseInt(menuId));
			sysCatalogDao.delListByAuthorithId(Integer.parseInt(menuId));
			sysAuthorityDao.delSysAuthority(Integer.parseInt(menuId));
		}else if("2".equals(menuLv)){
			sysActionDao.delListByCatalogId(Integer.parseInt(menuId));
			sysResourceDao.delListByCatalogId(Integer.parseInt(menuId));
			sysCatalogDao.delSysCatalog(Integer.parseInt(menuId));
		}else if("3".equals(menuLv)){
			sysActionDao.delListByResourceId(Integer.parseInt(menuId));
			sysResourceDao.delSysResource(Integer.parseInt(menuId));
		}else if("4".equals(menuLv)){
			sysActionDao.delSysAction(Integer.parseInt(menuId));
		}
		
		result.put("msg", "操作成功");
		return result;
	}
	
	/**
	 * 修改目录菜单
	 * @param menuLv 菜单等级
	 * @param menuId 菜单id
	 * @param menuUrl 菜单地址
	 * @param menuName 菜单名称
	 * @param menuSort 菜单排序数字
	 */
	public Map<String, Object> updateMenu(String menuLv, String menuId, String menuUrl, String menuName, String menuSort, String isbutton, String actioncode, String actionnote) throws Exception {
		Map<String, Object> result = new HashMap<String, Object>();
		
		if(StringUtils.isEmpty(menuLv) || StringUtils.isEmpty(menuId)){
			result.put("msg", "操作失败, 菜单等级 或 菜单ID 获取失败");
			return result;
		}else if("1".equals(menuLv)){
			SysAuthority authority = sysAuthorityDao.getSysAuthority(Integer.parseInt(menuId));
			authority.setAuthorityname(menuName);
			authority.setSort(Integer.parseInt(menuSort));
			sysAuthorityDao.updateSysAuthority(authority);
		}else if("2".equals(menuLv)){
			SysCatalog catalog = sysCatalogDao.getSysCatalog(Integer.parseInt(menuId));
			catalog.setCatalogname(menuName);
			catalog.setSort(Integer.parseInt(menuSort));
			sysCatalogDao.updateSysCatalog(catalog);
		}else if("3".equals(menuLv)){
			SysResource resource = sysResourceDao.getSysResource(Integer.parseInt(menuId));
			resource.setResourcename(menuName);
			resource.setSort(Integer.parseInt(menuSort));
			resource.setUrl(menuUrl);
			sysResourceDao.updateSysResource(resource);
		}else if("4".equals(menuLv)){
			SysAction action = sysActionDao.getSysAction(Integer.parseInt(menuId));
			action.setActionname(menuName);
			action.setSort(Integer.parseInt(menuSort));
			action.setUrl(menuUrl);
			action.setIsbutton(Integer.parseInt(isbutton));
			action.setCode(actioncode);
			action.setNote(actionnote);
			sysActionDao.updateSysAction(action);
		}
		
		result.put("msg", "操作成功");
		return result;
	}
	
	/**
	 * 获取目录菜单信息（单个菜单）
	 */
	public Map<String, Object> getMenuInfo(String menuLv, String menuId) throws Exception {
		Map<String, Object> result = new HashMap<String, Object>();
		if("1".equals(menuLv)){
			SysAuthority authority = sysAuthorityDao.getSysAuthority(Integer.parseInt(menuId));
			result.put("authority", authority);
		}else if("2".equals(menuLv)){
			SysCatalog catalog = sysCatalogDao.getSysCatalog(Integer.parseInt(menuId));
			SysAuthority authority = sysAuthorityDao.getSysAuthority(catalog.getAuthorityid());
			result.put("catalog", catalog);
			result.put("authority", authority);
		}else if("3".equals(menuLv)){
			SysResource resource = sysResourceDao.getSysResource(Integer.parseInt(menuId));
			SysCatalog catalog = sysCatalogDao.getSysCatalog(resource.getCatalogid());
			SysAuthority authority = sysAuthorityDao.getSysAuthority(catalog.getAuthorityid());
			result.put("resource", resource);
			result.put("catalog", catalog);
			result.put("authority", authority);
		}else if("4".equals(menuLv)){
			SysAction action = sysActionDao.getSysAction(Integer.parseInt(menuId));
			result.put("action", action);
		}
		result.put("msg", "操作成功");
		return result;
	}

	/**
	 * 获取 1,2,3,4级目录 for jsTree
	 * (第4级功能 会根据权限 标记 选中状态)
	 */
	public List<Map<String, Object>> getMenuListForJsTree(Integer roleId) throws Exception {
		List<Map<String, Object>> dataList = new ArrayList<Map<String,Object>>();
		//tree状态1
		Map<String, Object> stateOpen = new HashMap<String, Object>();
		stateOpen.put("opened", true);
		//tree状态2
		Map<String, Object> stateOpenSelect = new HashMap<String, Object>();
		stateOpenSelect.put("opened", true);
		stateOpenSelect.put("selected", true);
		
		//权限 现有的所有 功能
		List<Integer> haveActionList = roleId==null?new ArrayList<Integer>():sysRoleActionDao.getActionIdList(roleId);
		
		//获取一级目录
		List<SysAuthority> authorityList = sysAuthorityService.getList();
		for(SysAuthority authority : authorityList){
			List<Map<String, Object>> authorityChildrenList = new ArrayList<Map<String,Object>>();
			//获取二级目录
			List<SysCatalog> catalogList = sysCatalogService.getListByAuthorityId(authority.getId());
			for(SysCatalog catalog: catalogList){
				List<Map<String, Object>> catalogChildrenList = new ArrayList<Map<String,Object>>();
				//获取三级目录
				List<SysResource> resourceList = sysResourceService.getListByCatalogId(catalog.getId());
				for(SysResource resource : resourceList){
					List<Map<String, Object>> resourceChildrenList = new ArrayList<Map<String,Object>>();
					//获取四级目录
					List<SysAction> actionList = sysActionService.getListByResourceId(resource.getId());
					for(SysAction action : actionList){
						Map<String, Object> children = new HashMap<String, Object>();
						String text = (action.getIsbutton()==1?"「连接」":"「Button」")+" "+action.getActionname();
						children.put("text", text);
						children.put("id", action.getId());
						children.put("icon", "fa fa-th-list fa-fw");
						if(haveActionList.contains(action.getId())){
							children.put("state", stateOpenSelect);
						}
						resourceChildrenList.add(children);
					}
					Map<String, Object> resourceMap = new HashMap<String, Object>();
					resourceMap.put("text", resource.getResourcename());
					resourceMap.put("children", resourceChildrenList);
					resourceMap.put("state", stateOpen);
					
					catalogChildrenList.add(resourceMap);
				}
				Map<String, Object> catalogMap = new HashMap<String, Object>();
				catalogMap.put("text", catalog.getCatalogname());
				catalogMap.put("children", catalogChildrenList);
				catalogMap.put("state", stateOpen);
				
				authorityChildrenList.add(catalogMap);
			}
			Map<String, Object> authorityMap = new HashMap<String, Object>();
			authorityMap.put("text", authority.getAuthorityname());
			authorityMap.put("children", authorityChildrenList);
			authorityMap.put("state", stateOpen);
			
			dataList.add(authorityMap);
		}
		return dataList;
		
	}

	/**
	 * 获取目录菜单 For 登入成功，绑定给用户，用于 用户主页面显示
	 * @param authorityIds 1级目录参数 例如：1,2,4
	 * @param catalogIds 2级目录参数 例如：1,2,4
	 * @param resourceIds 3级目录参数 例如：1,2,4
	 */
	public List<SysAuthority> getMenuList(List authorityIdList, List catalogIdList, List resourceIdList) throws Exception {
		List<SysAuthority> allAuthorityList = sysAuthorityService.getList();
		List<SysAuthority> newAuthorityList = new ArrayList<SysAuthority>();
		for(SysAuthority authority : allAuthorityList){
			if(authorityIdList.contains(authority.getId())){
				List<SysCatalog> allCatalogList = sysCatalogService.getListByAuthorityId(authority.getId());
				List<SysCatalog> newCatalogList = new ArrayList<SysCatalog>();
				for(SysCatalog catalog: allCatalogList){
					if(catalogIdList.contains(catalog.getId())){
						List<SysResource> allResourceList = sysResourceService.getListByCatalogId(catalog.getId());
						List<SysResource> newResourceList = new ArrayList<SysResource>();
						for(SysResource resource : allResourceList){
							if(resourceIdList.contains(resource.getId())){
								newResourceList.add(resource);
							}
						}
						catalog.setResourceList(newResourceList);
						newCatalogList.add(catalog);
					}
				}
				authority.setCatalogList(newCatalogList);
				newAuthorityList.add(authority);
			}
		}
		return newAuthorityList;
	}

}
